#!usr/lib/python
# -*- coding:gb2312 -*-
"""
"""

import xml.etree.ElementTree as ET
class CXML():
    """"""
    XML_HEAD_STR    =   '<?xml version="1.0" encoding="utf-8"?>'
    def __init__(self,sfile=None,mode="r"):
        """ """
        self.pf     = None
        self.xml    = None
        if hasattr(sfile,"read"):
            self.pf = sfile;
        elif isinstance(sfile,str):
            self.pf = open(sfile,mode);
        elif sfile is None:
            pass
        else:
            pass

    def root(self):
        """ """
        if self.pf:
            self.pf.seek(0);
            self.xml = self.__parseXml(self.pf.read())
        return self.xml

    def children(self,node):
        """ """
        if hasattr(node,"getchildren"):
            return node.getchildren();
        return None
        
    def parse(self):
        xmlValue = None
        allnodes = {}
        root = self.root();
        if self.isEmptyText(root.text):
            allnodes[root.tag] = root.text;
            allnodes["attr"] = root.attrib;
            return allnodes;
        else:
            res = self.childrenList(self.children(root));
            if isinstance(res,dict):
                allnodes.update(res);
            else:
                allnodes[root.tag] = res;
            allnodes["attr"] = root.attrib;
        return allnodes
        
    def isEmptyText(self,text):
        text = text.replace("\n","")
        text = text.replace("\r","")
        text = text.replace(" ","")
        return text
    def childrenList(self,childrens):
        childs = []
        for node in childrens:
            n = {}
            n["attr"] = node.attrib;
            if self.isEmptyText(node.text):
                n[node.tag] = node.text;
            else:
                res = self.childrenList(self.children(node));
                if isinstance(res,dict):
                    n.update(res);
                else:
                    n[node.tag] = res;
            childs.append(n);
        return childs
        
    def xmlList(self,Listkeys=[]):
        """ """
        root = self.root();
        childrens = self.children(root)
        allnodes = []
        if childrens is None:
            return allnodes
        for child in childrens:
            allnodes.append(self.__nodeinfo__(child,Listkeys));
            #break;
        return allnodes

    def xmlDict(self,mainKey,ListKeys=[]):
        """ """
        nListKey = ListKeys;
        if len(nListKey)>=1 and mainKey not in nListKey:
            nListKey.append(mainKey)
        root = self.root();
        childrens = self.children(root)
        allnodes = {}
        if childrens is None:
            return allnodes
        for child in childrens:
            node = self.__nodeinfo__(child,nListKey);
            if node.has_key(mainKey):
                allnodes[node[mainKey]] = node
            else:
                raise KeyError,"%s not in node:%s"%(mainKey,node);
            #break;
        return allnodes
    def __nodeinfo__(self,node,keys=[]):
        """ """
        res = self.__unpacknode__(node,keys);
        #if not res or not res.has_key("tag"):
        #    return result
        return res;

    def __unpacknode__(self,node,keys=[]):
        """ """
        result = {}
        childrens = self.children(node);
        if not childrens :
            if node.tag in keys or not keys:
                #print {"tag":node.tag,"text":node.text};
                print dir(node)
                result = {"tag":node.tag,"text":node.text,"attr":node.attrib};
        for child in childrens:
            res = self.__unpacknode__(child,keys);
            #print "..a/",res
            if res.has_key("tag"):
                result = self.__upDict(result,res["tag"],res["text"])
            else:
                result = self.__upDict(result,child.tag,res)
        #print result
        return result

    def __parseXml(self,buf):
        """ """
        try:
            x   =   ET.XML(buf)
            return x;
        except Exception,e:
            print e
        return None

    def __toList(self,a):
        """ """
        try:
            if not isinstance(a,str):
                return list(a)
        except:
            pass
        return [a];
    def __upDict(self,kwd,key,value):
        """ """
        if key in kwd.keys():
            kwd[key] = self.__toList(kwd[key]);
            kwd[key].append(value)
        else:
            kwd[key]=value;
        return kwd
    def __del__(self):
        """ """
        if self.pf:
            try:
                self.pf.close()
            except:
                pass

if __name__ == "__main__":
    x = '<v><a>s</a><s>1</s></v>';
